/**
 * 向往阳光的图形管理器
 */
import {SizeRoot} from "./SizeRoot";
import {PathArray, PathInfo, RangeInfo} from "./PathInfo";
import {MultiPaths} from "./MultiPaths";
import {TextInfo} from "./TextInfo";
import {MatchColor} from "../colors/MatchColor";
import {SinglePath} from "./SinglePath";
import {Vertex2} from "../Math2D/Direction2D";

class ShapeManager extends SizeRoot {
    private _shapeObject0: {[key: string | 'range']: MultiPaths} = {}; //Dictionary写法
    private _shapeObjectWithdrawn: {[key: string]: MultiPaths} = {};
    textObject: Array<TextInfo> = [];
    border: PathInfo = {maxX: 0, maxY: 0, minX: 0, minY: 0, name: "path01", path: [], closed: false, fillStyle: "#FFFFFF"};

    get shapeObject() {
        let newShapeObject: Array<PathInfo> = [];
        let shapeObjectValues = Object.values(this._shapeObject0);
        for (let e of shapeObjectValues) {
            newShapeObject = newShapeObject.concat(e.multiPathInfo.shapes);
        }
        return newShapeObject;
    }

    reset = () => {
        let keys = Object.keys(this._shapeObject0);
        for (let key of keys) {
            this.removeSingleKey(key);
        }

        this.textObject.splice(0);
        this.ResetSizeRoot();
    }

    //移除一个键，清空一个数组
    removeSingleKey = (key: string) => {
        let multiPath = this._shapeObject0[key];
        multiPath.reset();
        this._shapeObjectWithdrawn[key] = multiPath;
        delete this._shapeObject0[key];
    }

    //添加一个文本
    addText = (text:string, x:number, y:number, fontSize?: number, fillColor?: string, align?:string) => {
        fontSize = fontSize || 16;
        fillColor = fillColor || "#000";
        align = align || "left";

        if (!MatchColor(fillColor)) return;

        this.textObject.push({
            text, fontSize, x, y, fillColor, align
        });
    };

    addPath = (path:PathArray, name?:string, fillColor?: string, strokeColor?:string, closed?: boolean) => {
        if (closed === undefined) closed = false;
        if (fillColor !== undefined && !MatchColor(fillColor)) {
            fillColor = "#F00";
        }

        if (strokeColor !== undefined && !MatchColor(strokeColor)) {
            strokeColor = "#000";
        }

        if (name === undefined) name = 'default';

        if (this._shapeObject0[name] === undefined) {
            let newMultiPath:MultiPaths;
            if (this._shapeObjectWithdrawn[name] !== undefined) {
                newMultiPath = this._shapeObjectWithdrawn[name];
            } else {
                newMultiPath = new MultiPaths();
            }
            this._shapeObject0[name] = newMultiPath;
        }

        let singleMultiPaths:MultiPaths = this._shapeObject0[name];

        let sp = new SinglePath(path);
        sp.SetRange();
        sp.SetFillColor(fillColor);
        sp.SetStrokeColor(strokeColor);
        let {sMinX, sMinY, sMaxX, sMaxY} = sp.GetRangeInfo();

        //当图形还没有显示内容的时候，对最小值最大值重新定义
        if (Object.values(this._shapeObject0).every(e => e.multiPathInfo.shapes.length === 0)) {
            this._minX = sMinX; this._maxX = sMaxX;
            this._minY = sMinY; this._maxY = sMaxY;
        }

        if (this._minX > sMinX) this._minX = sMinX;
        if (this._minY > sMinY) this._minY = sMinY;
        if (this._maxX < sMaxX) this._maxX = sMaxX;
        if (this._maxY < sMaxY) this._maxY = sMaxY;

        singleMultiPaths.addPath(path, fillColor, strokeColor, closed);
    };

    SetBorder = (range: RangeInfo) => {
        let {minX, minY, maxX, maxY} = range;
        let A: Vertex2 = [minX, minY];
        let B: Vertex2 = [maxX, minY];
        let C: Vertex2 = [maxX, maxY];
        let D: Vertex2 = [minX, maxY];
        this.border = {name: "border", path: [A, B, C, D], closed: true, fillStyle: "#FFFFFF", strokeStyle: "#000000", strokeWidth: 2,
            minX, minY, maxX, maxY};
        this._minX = minX; this._minY = minY;
        this._maxX = maxX; this._maxY = maxY;
    }
}

export {ShapeManager};